package com.cbd.common;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.IOException;
import java.util.Objects;

/**
 * cbd-management:
 * {@code @Description}  书写文件上传服务器中的指定路径
 * {@code @Author}  Flowen~
 * {@code @Date&Time} 2024/11/29 16:56
 */
@Service
@Slf4j
public class FileStorageService {

    @Value("${file.upload.dir}") // 从配置文件中读取上传目录配置
    private String uploadDir;

    // 私有方法用于检查并创建上传目录
    private void createUploadDirIfNotExists() {
        File uploadDirFile = new File(uploadDir);
        if (!uploadDirFile.exists()) {
            boolean created = uploadDirFile.mkdirs(); // 创建目录
            if (created) {
                log.info("创建上传目录: {}", uploadDirFile.getAbsolutePath());
            } else {
                log.error("上传目录创建失败: {}", uploadDirFile.getAbsolutePath());
                try {
                    throw new IOException("上传目录创建失败，无法保存文件");
                } catch (IOException e) {
                    log.error("上传目录创建失败，无法保存文件: {}", e.getMessage());
                    throw new RuntimeException(e);
                }
            }
        } else {
            log.info("上传目录已存在: {}", uploadDirFile.getAbsolutePath());
            // 权限检查
            if (!uploadDirFile.canWrite()) {
                log.error("上传目录没有写入权限: {}", uploadDirFile.getAbsolutePath());
                throw new SecurityException("当前路径没有写入权限，无法保存文件");
            }
        }
    }


    public String storeFile(MultipartFile file) throws IOException {
        // 在保存文件之前确保上传目录存在
        createUploadDirIfNotExists();
        log.info("开始保存文件: {}", file.getOriginalFilename());

        // 生成文件的完整路径
        String originalFilename = Objects.requireNonNull(file.getOriginalFilename());
        File destinationFile = new File(uploadDir, originalFilename);
        log.info("初始文件完整路径: {}", destinationFile.getAbsolutePath());

        // 处理文件名冲突
        if (destinationFile.exists()) {
            log.warn("文件已存在，使用已存在的文件名: {}", destinationFile.getName());
        } else {
            log.info("文件不存在，可以正常上传: {}", originalFilename);
        }


        log.info("最终文件保存路径: {}", destinationFile.getAbsolutePath());

// 保存文件
        try {
            // 检查输入文件是否存在且可读
            if (file == null || file.isEmpty()) {
                log.error("要保存的文件为空或无效");
                throw new IllegalArgumentException("要保存的文件无效");
            }

            // 检查目标目录是否存在
            if (!destinationFile.getParentFile().exists()) {
                log.warn("目标目录不存在，正在创建: {}", destinationFile.getParentFile().getAbsolutePath());
                destinationFile.getParentFile().mkdirs(); // 创建目录
            }

            // 最终检查目标文件路径
            if (destinationFile.exists()) {
                log.warn("文件已存在，使用新文件名: {}", destinationFile.getName());
            }

            file.transferTo(destinationFile); // 将文件保存到指定路径
            log.info("文件保存成功，绝对路径: {}", destinationFile.getAbsolutePath());
        } catch (IOException | IllegalArgumentException e) {
            log.error("文件保存失败: {}", e.getMessage());
            throw e; // 抛出异常以便调用者处理
        }


        return destinationFile.getAbsolutePath(); // 返回文件的绝对路径
    }
}
